/** 生成一个随机数组
 * @param {Int} len 生成数组的个数
 * @return {Array} 返回一个随机数数组
 */
function createArr(len) {
  const list = [];
  for (let i = 0; i < len; i++) {
    list.push(Math.floor(Math.random() * len));
  }
  return list;
}

function quickSort(list) {
  if (list.length <= 1) return list;
  const [middle, ...arr] = list;
  const left = [];
  const right = [];
  for (const item of arr) {
    if (item <= middle) {
      left.push(item);
    } else {
      right.push(item);
    }
  }
  return [...quickSort(left), middle, ...quickSort(right)];
}
console.time("快速排序");
quickSort(createArr(10000));
console.timeEnd("快速排序");

function bubbleSort(list) {
  for (let i = 0; i < list.length; i++) {
    for (let j = 0; j < list.length - 1 - i; j++) {
      if (list[j] > list[j + 1]) {
        [list[j], list[j + 1]] = [list[j + 1], list[j]];
      }
    }
  }
  return list;
}
console.time("冒泡排序");
bubbleSort(createArr(10000));
console.timeEnd("冒泡排序");

//  对于curry(foo) , g函数参数参数足够4个
//  就调用foo(a,b,c,d)
//  如果小于就返回一个可以累计参数的函数
const curry = func => {
  const g = (...allArgs) =>
    allArgs.length >= func.length
      ? func(...allArgs)
      : (...args) => g(...allArgs, ...args);
  return g;
};

const y = function(le) {
  return (function(f) {
    return f(f);
  })(function(f) {
    return le(function(...x) {
      return f(f)(...x);
    });
  });
};

const curryY = func =>
  y(g => {
    (...allArgs) => {
      allArgs.length >= func.length
        ? func(...allArgs)
        : (...args) => g(...allArgs, ...args);
    };
  });

const foo = curryY((a, b, c, d) => {
  console.log(a, b, c, d);
});

console.log(foo);
// foo(1)(2)(3)(4) //1234
// foo(1)(2)(3) // 不返回
// const f = foo(1)(2)(3) //
// f(5) // 1235
function solve(arr, N) {
  const s = new Set();
  for (let i = 0; i < arr.length; i++) {
    for (let j = 0 + 1; j < arr.length + 1; j++) {
      console.log(arr.slice(i, j));
      const remain = arr.slice(i, j).reduce((x, y) => x + y, 0) % N;
      s.add(remain);
    }
  }
  console.log("s", s);
  return s.has(0);
}
const c = solve([3, 9], 15);
console.log("c", c);

const students = [
  {
    id: 1,
    name: "Ruler",
    group_id: 1,
    score: 92
  },
  {
    id: 2,
    name: "Super",
    group_id: 1,
    score: 81
  },
  {
    id: 3,
    name: "Dog",
    group_id: 1,
    score: 30
  },
  {
    id: 4,
    name: "Beaty",
    group_id: 2,
    score: 75
  },
  {
    id: 5,
    name: "Jason",
    group_id: 2,
    score: 88
  },
  {
    id: 6,
    name: "Water",
    group_id: 2,
    score: 59
  },
  {
    id: 7,
    name: "Codez",
    group_id: 3,
    score: 21
  },
  {
    id: 8,
    name: "Wande",
    group_id: 3,
    score: 98
  },
  {
    id: 9,
    name: "Caous",
    group_id: 3,
    score: 67
  }
];
const groups = [
  {
    id: 1,
    name: "Red"
  },
  {
    id: 2,
    name: "Yellow"
  },
  {
    id: 3,
    name: "Green"
  }
];

const group = students.reduce((groups, student) => {
  groups[student.group_id] = [...(groups[student.group_id] || []), student];
  return groups;
}, {});

const join = students.map(student => {
  const group = groups.find(g => g.id === student.group_id);
  return {
    ...student,
    group_name: group.name
  };
});

function fallent(arr) {
  return eval(`[${arr + ""}]`);
}

const arr = [1, [2, 3, [4]], [5, 6, 7], [8, [9, 10]]];

// function flatten(arr) {
//   return [].concat(...arr.map(_ =>
//     Array.isArray(_) ? flatten(_) : _
//   ))
// }
// console.log(flatten(arr))

function* flatten(arr) {
  for (let i = 0; i < arr.length; i++) {
    if (Array.isArray(arr[i])) {
      yield flatten(arr[i]);
    } else {
      yield arr[i];
    }
  }
}
console.log(1, [...flatten(arr)]);

function insertSort(arr) {
  for (let i = 0; i < arr.length; i++) {
    let card = arr[i];
    let j = i;
    while (j > 0 && card < arr[j - 1]) {
      arr[j] = arr[j - 1];
      j--;
    }
    arr[j] = card;
  }
  return arr;
}
console.time("插入排序");
insertSort(createArr(10000));
console.timeEnd("插入排序");

function clone(obj) {
  if (obj === null || typeof obj !== "object") return obj;
  const newObj = obj.constructor();
  console.log("newObj", newObj);
  for (let key in Object.getOwnPropertyDescriptor(obj)) {
    newObj[key] = clone(obj[key]);
  }
  return newObj;
}
console.log(
  clone({
    a: {
      v: 1
    }
  })
);
